package ru.reaperoq.taskmanager.models

import jakarta.persistence.*
import lombok.Data
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.userdetails.UserDetails

@Data
@Entity(name = "users")
open class User(
    @Id @GeneratedValue(strategy = GenerationType.SEQUENCE)
    open val id: Long? = null,
    @JvmField
    @Column(nullable = false, unique = true, length = 64, name = "username")
    val username: String,
    @JvmField
    @Column(nullable = false, length = 72, name = "password")
    val password: String,
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    open val role: Role = Role.USER,

    @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY, mappedBy = "author")
    open val tasks: MutableSet<Task> = mutableSetOf(),

    @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY, mappedBy = "author")
    open val lists: MutableSet<TaskList> = mutableSetOf(),

    @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.LAZY, mappedBy = "id")
    open val timetables: MutableSet<Timetable> = mutableSetOf(),

    @ManyToMany
    @JoinTable(
        name = "user_files",
        joinColumns = [(JoinColumn(name = "user_id", referencedColumnName = "id"))],
        inverseJoinColumns = [(JoinColumn(name = "file_id", referencedColumnName = "id"))],
    )
    val files: MutableSet<File> = mutableSetOf(),

    @ManyToOne
    @JoinColumn(name = "avatar_id")
    val avatar: File? = null

) : UserDetails {
    enum class Role {
        USER, ADMIN, MODERATOR
    }

    override fun getAuthorities(): Collection<GrantedAuthority> {
        return listOf(SimpleGrantedAuthority(role.name))
    }

    override fun getPassword(): String =
        password

    override fun getUsername(): String =
        username

    override fun isAccountNonExpired(): Boolean = true

    override fun isAccountNonLocked(): Boolean = true

    override fun isCredentialsNonExpired(): Boolean = true

    override fun isEnabled(): Boolean = true
}